﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dude.Data.Meta
{
    public abstract class SQLCreateScriptBuiderBase: IDataModelVisitor
    {
        public SQLCreateScriptBuiderBase()
        {
        }

        public virtual void Process(IVisitedDataModel dataModelObject)
        {
            dataModelObject.VisitedDataModel(this);
        }

        protected virtual object StartDataModel(DataModel dataModel) { return null; }
        protected virtual void StopDataModel(DataModel dataModel, object data) { }

        protected virtual object StartDatabaseConnectionInfo(DatabaseConnectionInfo databaseConnectionInfo) { return null; }
        protected virtual void StopDatabaseConnectionInfo(DatabaseConnectionInfo databaseConnectionInfo, object data) { }

        protected virtual object StartDatabaseInfo(DatabaseInfo databaseInfo) { return null; }
        protected virtual void StopDatabaseInfo(DatabaseInfo databaseInfo, object data) { }

        protected virtual object StartTableInfo(TableInfo tableInfo) { return null; }
        protected virtual void StopTableInfo(TableInfo tableInfo, object data) { }

        protected virtual object StartDataFieldInfo(DataFieldInfo fieldInfo) { return null; }
        protected virtual void StopDataFieldInfo(DataFieldInfo fieldInfo, object data) { }

        #region IDataModelVisitor Members

        public void VisitDataModel(DataModel visited)
        {
            object data = StartDataModel(visited);
            foreach (DatabaseInfo db in visited.Databases)
            {
                db.VisitedDataModel(this);
            }
            StopDataModel(visited, data);
        }

        public void VisitDatabaseConnectionInfo(DatabaseConnectionInfo visited)
        {
            object data = StartDatabaseConnectionInfo(visited);
            StopDatabaseConnectionInfo(visited, data);
        }

        public void VisitDatabaseInfo(DatabaseInfo visited)
        {
            object data = StartDatabaseInfo(visited);

            if (visited.DataModel != null)
            {
                foreach (DatabaseConnectionInfo info in visited.DataModel.Connections)
                {
                    if ((info.ConnectionName == visited.ConnectionName) || info.Aliases.Contains(visited.ConnectionName))
                    {
                        info.VisitedDataModel(this);
                        break;
                    }
                }
            }

            foreach (TableInfo table in visited.Tables)
            {
                table.VisitedDataModel(this);
            }
            StopDatabaseInfo(visited, data);
        }

        public void VisitTableInfo(TableInfo visited)
        {
            object data = StartTableInfo(visited);
            foreach (DataFieldInfo field in visited.Fields)
            {
                field.VisitedDataModel(this);
            }
            StopTableInfo(visited, data);
        }

        public void VisitFieldInfo(DataFieldInfo visited)
        {
            object data = StartDataFieldInfo(visited);
            StopDataFieldInfo(visited, data);
        }

        #endregion
    }
}
